package blackstar.plugin.jmxproxy;

import java.util.HashMap;
import java.util.Map;

import javax.management.remote.JMXConnectorServer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.event.Event;
import blackstar.agent.event.EventDispatcherSupport;
import blackstar.agent.event.EventListener;
import blackstar.agent.event.ShutdownEvent;
import blackstar.agent.event.StartupEvent;
import blackstar.agent.jvm.JMXProxy;
import blackstar.agent.jvm.JMXProxyShutdownEvent;
import blackstar.agent.jvm.JMXProxyStartupEvent;

/**
 * @author RayWoo (ayufox@gmail.com)
 * 
 */
public class JMXRemoteProxyManager extends EventDispatcherSupport implements
		EventListener
{
	private final static Log LOGGER = LogFactory
			.getLog(JMXRemoteProxyManager.class);

	private JMXConnectorServer connectorServer;
	private Map<String, JMXRemoteProxy> remoteProxies = new HashMap<String, JMXRemoteProxy>();

	public Class[] events()
	{
		return new Class[]
		{ StartupEvent.class, ShutdownEvent.class, JMXProxyStartupEvent.class,
				JMXProxyShutdownEvent.class };
	}

	public void onEvent(Event event) throws Exception
	{
		if (event instanceof StartupEvent)
		{
			startup();
		} else if (event instanceof ShutdownEvent)
		{
			shutdown();
		} else if (event instanceof JMXProxyStartupEvent)
		{
			startup(((JMXProxyStartupEvent) event).getJMXProxy());
		} else if (event instanceof JMXProxyShutdownEvent)
		{
			shutdown(((JMXProxyShutdownEvent) event).getJMXProxy());
		}
	}

	private void startup()
	{
		try
		{
			connectorServer = JMXRemoteProxyUtil
					.createJMXConnectorServer("/agent");
			connectorServer.start();

		} catch (Exception e)
		{
			LOGGER.error("Start JMXRemoteProxyManager failed", e);

			return;
		}
	}

	private void shutdown()
	{
		if (connectorServer != null)
		{
			try
			{
				connectorServer.stop();
			} catch (Exception e)
			{
				LOGGER.error("Stop JMXRemoteProxyManager failed", e);
			}

			connectorServer = null;
		}

		LOGGER.info("Stop JMXRemoteProxyManager success");
	}

	private void startup(JMXProxy proxy)
	{
		LOGGER.info("startup RemoteProxy[" + proxy.getId() + "]");
		JMXRemoteProxy remoteProxy = new JMXRemoteProxy(proxy);
		remoteProxy.start();
		remoteProxies.put(proxy.getId(), remoteProxy);
	}

	private void shutdown(JMXProxy proxy)
	{
		JMXRemoteProxy remoteProxy = remoteProxies.get(proxy.getId());
		if (remoteProxy != null)
		{
			LOGGER.info("shutdown RemoteProxy[" + proxy.getId() + "]");

			remoteProxy.stop();
		}
	}
}
